﻿
using QLKS2014.BLL;
using QLKS2014.PUBLIC;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace QLKS2014.GUI.StupidContent
{
    /// <summary>
    /// màn hình hóa đơn thanh tóa
    /// </summary>
    public partial class Bill : UserControl, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string _PropertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(_PropertyName));
        }

        #region variable
        
        ObservableCollection<PhongPublic> _ocPhong;

        public ObservableCollection<PhongPublic> OcPhong
        {
            get { return _ocPhong; }
            set
            {
                _ocPhong = value;
                OnPropertyChanged("OcPhong");
            }
        }

        ObservableCollection<PhongPublic> _ocPhongSeThanhToan;

        public ObservableCollection<PhongPublic> OcPhongSeThanhToan
        {
            get { return _ocPhongSeThanhToan; }
            set
            {
                _ocPhong = value;
                OnPropertyChanged("OcPhongSeThanhToan");
            }
        }

        decimal _triGia;

        public decimal TriGia
        {
            get { return _triGia; }
            set { _triGia = value;
            OnPropertyChanged("TriGia");
            }
        }

        #endregion

        #region Initialize
        public Bill()
        {
            InitializeComponent();
            _initializeControl();
            Loaded += Bill_Loaded;
        }

        private void _initializeControl()
        {
            _ocPhongSeThanhToan = new ObservableCollection<PhongPublic>();
        }

        void Bill_Loaded(object sender, RoutedEventArgs e)
        {
            _initialize();
        }

        private void _initialize()
        {
            List<PhongPublic> lPhong = new PhongBll().selectPhongNotEmpty();
            if (lPhong != null)
                OcPhong = new ObservableCollection<PhongPublic>(lPhong);
            else
                OcPhong = new ObservableCollection<PhongPublic>();

            if (cbbRoom.HasItems && cbbRoom.SelectedIndex == -1)
                cbbRoom.SelectedIndex = 0;

            this.txtbCustomer.Focus();
        }

        #endregion
 
        #region event
        //kiem tra nhap so
        private void txtbDiscount_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            Regex regex = new Regex("^[0-9]+");
            bool match = regex.IsMatch(e.Text);
            e.Handled = !match;
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            _saveBill();

        }


        private void UserControl_KeyDown(object sender, KeyEventArgs e)
        {
            //if (e.Key == Key.Enter)
            //{
            //    try
            //    {
            //        if (string.IsNullOrEmpty(this.tbDiscount.Text))
            //            this.tbDiscount.Text = "0";
            //        if (string.IsNullOrEmpty(this.tbxCustomer.Text) ||
            //            string.IsNullOrEmpty(this.tbxAdress.Text))
            //        {
            //            MessageBox.Show("Nhập đầy đủ thông tin", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            //            return;
            //        }
            //        DateTime dateBuild = DateTime.Now;
            //        dataBill.addNewBill(this.tbxCustomer.Text, dateBuild,
            //            this.tbxAdress.Text,
            //            nameRoom, float.Parse(this.tbDiscount.Text));
            //        MessageBox.Show("Lưu lại thành công", "Lưu dữ liệu", MessageBoxButton.OK);
            //    }
            //    catch
            //    {
            //        MessageBox.Show("Thao tác bị lỗi", "Lưu dữ liệu", MessageBoxButton.OK);
            //    }
            //}
        }

        /// <summary>
        /// them mot phong vao danh sach nhung phong can thanh toan
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAddRoomToBill_Click(object sender, RoutedEventArgs e)
        {
            _addRoomToBill();
            _updateTriGia();

        }



        private void cbbRoom_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                this.btnAddRoomToBill.Focus();
            }
            catch
            { }
        }

        private void dgRoom_KeyDown(object sender, KeyEventArgs e)
        {
            if ((Keyboard.Modifiers == ModifierKeys.Shift) && e.Key == Key.Delete)
            {
                MessageBoxResult result = MessageBox.Show("Bạn có muốn xóa phòng này không?", "Nhắc Nhở", MessageBoxButton.YesNo, MessageBoxImage.Warning);
                if (result == MessageBoxResult.Yes)
                {
                    DataGrid dgData = sender as DataGrid;
                    _deleteRooms(dgData);
                }
                return;
            }
        }

        private void _deleteRooms(DataGrid dgData)
        {
            IList selectedItems = dgData.SelectedItems;
            if (selectedItems == null)
                return;
            int size = selectedItems.Count;
            for (int i = size - 1; i >= 0; i--)
            {
                PhongPublic item = selectedItems[i] as PhongPublic;
                OcPhongSeThanhToan.Remove(item);
            }
        }

        private void dgRoom_LoadingRow(object sender, DataGridRowEventArgs e)
        {

        }

       #endregion

        #region caculator money for bill

        private void _updateTriGia()
        {
            int chietKhau = int.Parse(txtbDiscount.Text);
            TriGia = _calcTriGiaHoaDon(OcPhongSeThanhToan, chietKhau);
        }

        private decimal _calcTriGiaHoaDon(ObservableCollection<PhongPublic> ocPhongSeThanhToan_, int chietKhau_)
        {
            decimal totalCost = 0;
            // 1. tinh tong tien tung phong
            foreach (PhongPublic item in ocPhongSeThanhToan_)
            {
                totalCost += _calcTotalMoneyForARoom(item);
            }


            // 2. cong lai va tru di chiet khau
            if (chietKhau_ > 0)
                totalCost = totalCost - totalCost * chietKhau_ / 100;

            return totalCost;
        }

        private decimal _calcTotalMoneyForARoom(PhongPublic item)
        {
            PhieuThuePhongPublic phieuThuePhong0 = _getPhieuThuePhongByMaPhong(item);
            if (phieuThuePhong0 == null)
                return 0;

            decimal roomPrice = item.DonGia;
            int totalCustomer = phieuThuePhong0.SoLuong;
            bool isOverFlow = totalCustomer > 2;
            bool hasForeigner = _checkForeigner(phieuThuePhong0);
            DateTime ngayThue = phieuThuePhong0.NgayThue;
            DateTime ngayTra = DateTime.Now;
            int totalDay = ngayTra.Day - ngayThue.Day;


            decimal total = _calcTotalMoneyForARoom(roomPrice, isOverFlow, hasForeigner, totalDay, totalCustomer);
            return total;
        }

        private bool _checkForeigner(PhieuThuePhongPublic phieuThuePhong0)
        {
            int maPhieuThue = phieuThuePhong0.MaPhieuThue;
            ChiTietPhieuThuePhongPublic ctPhieuThuePhong = new ChiTietPhieuThuePhongPublic();
            ctPhieuThuePhong.MaPhieuThue = maPhieuThue;
            var lCTPhieuThuePhong = new ChiTietPhieuThuePhongBll().ChiTietPhieuThuePhong_SelectByMaPhieuThue(ctPhieuThuePhong);
            if (lCTPhieuThuePhong == null)
                return false;
            foreach (var item in lCTPhieuThuePhong)
            {
                LoaiKhachHangPublic loaiKhach0 = new LoaiKhachHangPublic();
                loaiKhach0.MaLoaiKhachHang = item.MaLoaiKhachHang;
                var lLoaiKhach = new LoaiKhachHangBll().selectByMaLoaiKhachHang(loaiKhach0);
                if (lLoaiKhach != null && lLoaiKhach.Count > 0)
                    return true;

            }
            return false;
        }

        private decimal _calcTotalMoneyForARoom(decimal roomPrice, bool overFlow, bool hasForeigner, int totalDate_, int totalCustomer_)
        {
            decimal totalMoney = 0;
            totalMoney = totalDate_ * roomPrice;

            decimal foreignerCostPlus = 0;
            decimal overFlowCostPlus = 0;
            if (overFlow)
                overFlowCostPlus = _getCostPlusWhenOverFlow(roomPrice);
            if (hasForeigner)
                foreignerCostPlus = _getCostPlusWhenHasForeigner(roomPrice);

            totalMoney = totalMoney + foreignerCostPlus + overFlowCostPlus;
            return totalMoney;
        }

        private int _getRoomTotalCustomer(PhongPublic item)
        {
            PhieuThuePhongPublic phieuThuePhong0 = new PhieuThuePhongPublic();
            phieuThuePhong0.MaPhong = item.MaPhong;
            var lPhieuThuePhong = new PhieuThuePhongBll().selectByMaxMaPhieuThue_Tmp(phieuThuePhong0);//=> get lastest phieu thue phong by ma phong
            if (lPhieuThuePhong == null || lPhieuThuePhong.Count == 0)
            {
                return 0;
            }
            int soKhachThue = lPhieuThuePhong[lPhieuThuePhong.Count - 1].SoLuong;
            return soKhachThue;
        }

        private decimal _getCostPlusWhenOverFlow(decimal roomPrice)
        {
            List<ThamSoPublic> lThamSo = new List<ThamSoPublic>();
            //new ThamSoBll();
            float tiLePhuThuOverFlow = new ThamSoBll().selectAll()[2].GiaTri;//int tiLePhuThuOverFlow = lThamSo[x].GiaTri;

            if (tiLePhuThuOverFlow > 0)
                return roomPrice * (decimal)tiLePhuThuOverFlow / 100;
            return 0;
        }

        private decimal _getCostPlusWhenHasForeigner(decimal roomPrice)
        {
            LoaiKhachHangPublic loaiKhach = new LoaiKhachHangPublic();
            loaiKhach.TenLoaiKhachHang = "Nước Ngoài";
            var lLoaiKhach = new LoaiKhachHangBll().selectByName(loaiKhach);
            if (lLoaiKhach == null || lLoaiKhach.Count == 0)
                return 0;
            float tiLePhuThuForeigner = lLoaiKhach[0].TyLePhuThu;
            //int tiLePhuThuOverFlow = lThamSo[x].GiaTri;
            if (tiLePhuThuForeigner > 0)
                return roomPrice * (decimal)tiLePhuThuForeigner / 100;
            return 0;
        }

        #endregion

        
        
        // insert new room to phong which will be bill
        private void _insertToPhongSeThanhToan(PhongPublic phongPublic_)
        {
            OcPhongSeThanhToan.Add(phongPublic_);
            OnPropertyChanged("OcPhongSeThanhToan");
        }

        private void _saveBill()
        {
            if (_checkSaveBillInput())
            {
                // 1. insert hoa don
                HoaDonPublic hoaDon0 = new HoaDonPublic();
                hoaDon0.NgayLap = DateTime.Now;
                hoaDon0.TenKhachHang = txtbCustomer.Text;
                hoaDon0.TriGia = _triGia;
                new HoaDonBll().insert(hoaDon0);// insert new hoa don

                
                //2. insert chi tiet hoa don
                int maHoaDon = 0; // get Ma hoa don here !!!!!!!!!!!!!!!!!!!!!
                var lHoaDon = new HoaDonBll().selectAll();
                if (lHoaDon != null && lHoaDon.Count > 0)
                    maHoaDon = lHoaDon[lHoaDon.Count - 1].MaHoaDon;
                else
                {
                    MessageBox.Show("Lưu hóa đơn bị lỗi!");
                    return;
                }

                foreach (PhongPublic item in OcPhongSeThanhToan)
                {
                    ChiTietHoaDonPublic ctHoaDon0 = new ChiTietHoaDonPublic();
                    ctHoaDon0.MaHoaDon = maHoaDon;

                    PhieuThuePhongPublic phieuThue = _getPhieuThuePhongByMaPhong(item);
                    ctHoaDon0.MaPhieuThue = phieuThue.MaPhieuThue; // => get ma phieu thue
                    ctHoaDon0.SoNgayThue = (DateTime.Now.Day - phieuThue.NgayThue.Day);// calc SoNgayThue
                    new ChiTietHoaDonBll().insert(ctHoaDon0);

                    // don't forget make room free
                    new PhongBll().update_Trong(item);
                }

                MessageBox.Show("Tạo hóa đơn thành công!");
                _reset();
            }
            else
            {
                MessageBox.Show("Mời nhập đầy đủ thông tin!");
            }
        }

        private bool _checkSaveBillInput()
        {
            return !(String.IsNullOrEmpty(txtbCustomer.Text) || String.IsNullOrEmpty(txtbAdress.Text) || String.IsNullOrEmpty(txtbDiscount.Text));
        }

        private PhieuThuePhongPublic _getPhieuThuePhongByMaPhong(PhongPublic phong0)
        {
            PhieuThuePhongPublic phieuThuePhong0 = new PhieuThuePhongPublic();
            phieuThuePhong0.MaPhong = phong0.MaPhong;
            var lPhieuThuePhong = new PhieuThuePhongBll().selectByMaxMaPhieuThue_Tmp(phieuThuePhong0);//=> get lastest phieu thue phong by ma phong
            if (lPhieuThuePhong == null || lPhieuThuePhong.Count == 0)
            {
                return null;
            }
            phieuThuePhong0 = lPhieuThuePhong[lPhieuThuePhong.Count - 1];
            return phieuThuePhong0;
        }

        private void _addRoomToBill()
        {
            if (_checkAddRoomToBillInput())
            {
                PhongPublic phong0 = cbbRoom.SelectedItem as PhongPublic;

                // insert room to phongsethanhtoan
                _insertToPhongSeThanhToan(phong0);
            }
            else
            {
                MessageBox.Show("Mời nhập đầy đủ thông tin!");
            }
        }

        private bool _checkAddRoomToBillInput()
        {
            return !(String.IsNullOrEmpty(txtbCustomer.Text) || String.IsNullOrEmpty(txtbAdress.Text) || String.IsNullOrEmpty(txtbDiscount.Text) || String.IsNullOrEmpty(cbbRoom.Text));
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            _reset();
        }

        private void _reset()
        {
            txtbAdress.Text = "";
            txtbCustomer.Text = "";
            txtbDiscount.Text = "0";
            OcPhongSeThanhToan.Clear();
            if (cbbRoom.HasItems)
                cbbRoom.SelectedIndex = 0;
            TriGia = 0;
        }

    }
}
